package com.tvein.system.controller.FileLoader
{
	//flash
	import flash.net.LocalConnection;
	import flash.events.Event;
	import flash.net.URLLoader;
	import flash.net.URLRequest;
	import flash.net.URLLoaderDataFormat;
	//pureMVC
	import org.puremvc.as3.multicore.interfaces.ICommand;
	import org.puremvc.as3.multicore.interfaces.INotification;
	import org.puremvc.as3.multicore.patterns.command.SimpleCommand;
	//custom
	import com.tvein.system.common.CommonConstants;
	import com.tvein.system.model.ServerProxy;
	import com.tvein.system.model.FilesProxy;
	import com.tvein.system.model.P2PFile;
//
	public class FileDownload extends SimpleCommand implements ICommand
	{
		private var serverData:ServerProxy;
		private var filesData:FilesProxy;
		private var targetChannel:String;
		
		override public function execute(notification:INotification) : void
		{
			serverData = facade.retrieveProxy( ServerProxy.NAME ) as ServerProxy;
			filesData = facade.retrieveProxy( FilesProxy.NAME ) as FilesProxy;
			
			targetChannel = notification.getBody()[0];
			
			getFile(notification.getBody()[1], notification.getBody()[2]);
		}
		
		private function getFile(fileSrc:String, fileVersion:String):void
		{
			//test file
			for (var i:int = 0; i < filesData.filesArray.length; i++)
			{
				if ((filesData.filesArray[i].fileSrc == fileSrc) && (filesData.filesArray[i].fileVersion == fileVersion))
				{
					loadDone(filesData.filesArray[i]);
					return;
				}
			}
			
			//try p2p
			
			if (serverData.p2pValue)
			{
				var p2pFile:P2PFile = new P2PFile(serverData.serverXML.rtmfpServer.rtmfp.@address);
				p2pFile.fileSrc = fileSrc;
				p2pFile.fileVersion = fileVersion;
				p2pFile.addEventListener(Event.CLOSE, _fileShareClose);
				p2pFile.addEventListener(Event.CANCEL, _fileShareCancel);
				p2pFile.addEventListener(Event.COMPLETE, _fileShareComplete);
				p2pFile.getFile();
			}
			else
			{
				loadFile(fileSrc, fileVersion);
			}
		}
		
		//p2p rejected
		private function _fileShareClose(evt:Event):void
		{
			evt.target.removeEventListener(Event.CLOSE, _fileShareClose);
			evt.target.removeEventListener(Event.CANCEL, _fileShareCancel);
			evt.target.removeEventListener(Event.COMPLETE, _fileShareComplete);
			
			evt.target.closeP2P();
			
			loadFile(evt.target.fileSrc, evt.target.fileVersion);
			
			serverData.p2pValue = false;
		}
		
		//p2p failed
		private function _fileShareCancel(evt:Event):void
		{
			evt.target.removeEventListener(Event.CLOSE, _fileShareClose);
			evt.target.removeEventListener(Event.CANCEL, _fileShareCancel);
			evt.target.removeEventListener(Event.COMPLETE, _fileShareComplete);
			
			evt.target.closeP2P();
			
			loadFile(evt.target.fileSrc, evt.target.fileVersion);
			
			serverData.p2pValue = false;
		}
		
		private function _fileShareComplete(evt:Event):void
		{
			evt.target.removeEventListener(Event.CLOSE, _fileShareClose);
			evt.target.removeEventListener(Event.CANCEL, _fileShareCancel);
			evt.target.removeEventListener(Event.COMPLETE, _fileShareComplete);
			
			filesData.fileAdd(evt.target as P2PFile);
			
			loadDone(evt.target as P2PFile);
		}
		
		public function loadFile(fileSrc:String, fileVersion:String):void
		{
			var loader:URLLoader = new URLLoader();
			loader.dataFormat = URLLoaderDataFormat.BINARY;
			loader.addEventListener(Event.COMPLETE, function(evt:Event):void {_fileLoaded(evt, fileSrc, fileVersion);});
			loader.load(new URLRequest(srcSever() + fileSrc));
		}
		
		private function srcSever():String
		{
			var i:int = Math.floor(Math.random() * serverData.srcServer.length());
			return (serverData.srcServer[i].@address);
		}
		
		private function _fileLoaded(evt:Event, fileSrc:String, fileVersion:String):void
		{
			evt.target.removeEventListener(Event.COMPLETE, _fileLoaded);
			
			var p2pFile:P2PFile = new P2PFile(serverData.serverXML.rtmfpServer.rtmfp.@address);
			p2pFile.fileSrc = fileSrc;
			p2pFile.fileVersion = fileVersion;
			p2pFile.fileData = evt.target.data;
			
			if (serverData.p2pValue)
			{
				p2pFile.shareFile();
			}
			else
			{
				p2pFile.splitFile();
			}
			
			filesData.fileAdd(p2pFile);
			
			loadDone(p2pFile);
		}
		
		public function loadDone(p2pFile:P2PFile):void
		{			
			var localConnection:LocalConnection = new LocalConnection();
			
			for (var i:int = p2pFile.fileChunks.length; i > 0 ; i--)
			{
				localConnection.send(targetChannel, "console", ["/fileloader -F", [p2pFile.fileSrc + "|" + p2pFile.fileVersion, i - 1, p2pFile.fileChunks[i - 1]]]);
			}
			
			localConnection = null;
		}
	}
}